package com.srp.backend.service;

import com.srp.backend.dto.FileUploadResponse;
import com.srp.backend.entity.FileUpload;
import com.srp.backend.mapper.FileUploadMapper;
import com.srp.backend.mapper.UserMapper;
import com.srp.backend.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;


import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 文件上传服务
 */
@Service
public class FileUploadService {
    
    @Autowired
    private FileUploadMapper fileUploadMapper;
    
    @Autowired
    private UserMapper userMapper;
    
    @Value("${app.upload-path:./uploads/}")
    private String uploadPath;
    
    @Value("${server.port:8080}")
    private String serverPort;
    
    // 允许的文件类型
    private static final Set<String> ALLOWED_EXTENSIONS = Set.of(
        "pdf", "doc", "docx", "txt", "md", "rtf",
        "jpg", "jpeg", "png", "gif", "bmp", "webp",
        "mp4", "avi", "mov", "wmv", "flv", "mkv",
        "mp3", "wav", "flac", "aac", "ogg",
        "zip", "rar", "7z", "tar", "gz",
        "xlsx", "xls", "ppt", "pptx"
    );
    
    // 最大文件大小（50MB）
    private static final long MAX_FILE_SIZE = 50 * 1024 * 1024;
    
    /**
     * 单文件上传
     */
    public FileUploadResponse uploadFile(MultipartFile file, String description) {
        validateFile(file);
        
        // 获取当前用户
        Long currentUserId = getCurrentUserId();
        String currentUsername = getCurrentUsername();
        
        // 创建上传目录
        createUploadDirectory();
        
        // 生成文件名和路径
        String originalFileName = file.getOriginalFilename();
        String fileExtension = getFileExtension(originalFileName);
        String storedFileName = generateFileName(fileExtension);
        String filePath = uploadPath + storedFileName;
        
        try {
            // 保存文件到磁盘
            Path targetPath = Paths.get(filePath);
            Files.copy(file.getInputStream(), targetPath);
            
            // 保存文件信息到数据库
            FileUpload fileUpload = FileUpload.builder()
                .originalFileName(originalFileName)
                .storedFileName(storedFileName)
                .filePath(filePath)
                .fileSize(file.getSize())
                .contentType(file.getContentType())
                .fileExtension(fileExtension)
                .description(description)
                .uploadUserId(currentUserId)
                .status(1)
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();
            
            fileUploadMapper.insert(fileUpload);
            
            // 构建响应
            return buildFileUploadResponse(fileUpload, currentUsername);
            
        } catch (IOException e) {
            throw new RuntimeException("文件保存失败: " + e.getMessage());
        }
    }
    
    /**
     * 多文件上传
     */
    public List<FileUploadResponse> uploadFiles(MultipartFile[] files, String description) {
        if (files == null || files.length == 0) {
            throw new RuntimeException("请选择要上传的文件");
        }
        
        if (files.length > 10) {
            throw new RuntimeException("一次最多只能上传10个文件");
        }
        
        List<FileUploadResponse> responses = new ArrayList<>();
        
        for (MultipartFile file : files) {
            if (!file.isEmpty()) {
                FileUploadResponse response = uploadFile(file, description);
                responses.add(response);
            }
        }
        
        return responses;
    }
    
    /**
     * 获取文件列表
     */
    public List<FileUploadResponse> getFileList(Integer page, Integer size) {
        if (page < 1) page = 1;
        if (size < 1 || size > 100) size = 10;
        
        Integer offset = (page - 1) * size;
        
        List<FileUpload> files = fileUploadMapper.selectAllWithPage(offset, size);
        
        return files.stream()
            .map(this::convertToResponse)
            .collect(Collectors.toList());
    }
    
    /**
     * 删除文件
     */
    @Transactional
    public void deleteFile(Long fileId) {
        // 1. 查询文件信息
        FileUpload fileUpload = fileUploadMapper.selectById(fileId);
        if (fileUpload == null) {
            throw new RuntimeException("文件不存在");
        }
        
        // 2. 检查权限（只能删除自己上传的文件）
        Long currentUserId = getCurrentUserId();
        if (!fileUpload.getUploadUserId().equals(currentUserId)) {
            // 这里可以添加管理员权限检查
            throw new RuntimeException("无权限删除此文件");
        }
        
        // 3. 先删除物理文件
        try {
            Path filePath = Paths.get(fileUpload.getFilePath());
            boolean fileDeleted = Files.deleteIfExists(filePath);
            if (!fileDeleted) {
                System.err.println("物理文件不存在或已被删除: " + fileUpload.getFilePath());
            }
        } catch (IOException e) {
            // 如果删除物理文件失败，记录错误但继续删除数据库记录
            System.err.println("删除物理文件失败: " + e.getMessage());
        }
        
        // 4. 删除数据库记录
        fileUploadMapper.deleteById(fileId);
    }
    
    /**
     * 获取文件信息
     */
    public FileUploadResponse getFileInfo(Long fileId) {
        FileUpload fileUpload = fileUploadMapper.selectById(fileId);
        if (fileUpload == null) {
            throw new RuntimeException("文件不存在");
        }
        
        return convertToResponse(fileUpload);
    }
    
    /**
     * 验证文件
     */
    private void validateFile(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            throw new RuntimeException("请选择要上传的文件");
        }
        
        // 检查文件大小
        if (file.getSize() > MAX_FILE_SIZE) {
            throw new RuntimeException("文件大小不能超过50MB");
        }
        
        // 检查文件名
        String originalFileName = file.getOriginalFilename();
        if (originalFileName == null || originalFileName.trim().isEmpty()) {
            throw new RuntimeException("文件名不能为空");
        }
        
        // 检查文件扩展名
        String fileExtension = getFileExtension(originalFileName);
        if (!ALLOWED_EXTENSIONS.contains(fileExtension.toLowerCase())) {
            throw new RuntimeException("不支持的文件类型: " + fileExtension);
        }
        
        // 检查文件名安全性
        if (originalFileName.contains("..") || originalFileName.contains("/") || originalFileName.contains("\\")) {
            throw new RuntimeException("文件名包含非法字符");
        }
    }
    
    /**
     * 创建上传目录
     */
    private void createUploadDirectory() {
        try {
            Path uploadDir = Paths.get(uploadPath);
            if (!Files.exists(uploadDir)) {
                Files.createDirectories(uploadDir);
            }
        } catch (IOException e) {
            throw new RuntimeException("创建上传目录失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String fileName) {
        if (fileName == null || !fileName.contains(".")) {
            return "";
        }
        return fileName.substring(fileName.lastIndexOf(".") + 1);
    }
    
    /**
     * 生成唯一文件名
     */
    private String generateFileName(String extension) {
        String uuid = UUID.randomUUID().toString().replace("-", "");
        String timestamp = String.valueOf(System.currentTimeMillis());
        return timestamp + "_" + uuid + "." + extension;
    }
    
    /**
     * 获取当前用户ID
     */
    private Long getCurrentUserId() {
        String username = getCurrentUsername();
        User user = userMapper.findByUsername(username);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        return user.getId();
    }
    
    /**
     * 获取当前用户名
     */
    private String getCurrentUsername() {
        return SecurityContextHolder.getContext().getAuthentication().getName();
    }
    
    /**
     * 构建文件上传响应
     */
    private FileUploadResponse buildFileUploadResponse(FileUpload fileUpload, String username) {
        return FileUploadResponse.builder()
            .id(fileUpload.getId())
            .originalFileName(fileUpload.getOriginalFileName())
            .storedFileName(fileUpload.getStoredFileName())
            .filePath(fileUpload.getFilePath())
            .fileUrl(generateFileUrl(fileUpload.getStoredFileName()))
            .fileSize(fileUpload.getFileSize())
            .contentType(fileUpload.getContentType())
            .fileExtension(fileUpload.getFileExtension())
            .description(fileUpload.getDescription())
            .uploadUserId(fileUpload.getUploadUserId())
            .uploadUsername(username)
            .uploadTime(fileUpload.getCreateTime())
            .status(fileUpload.getStatus())
            .build();
    }
    
    /**
     * 转换为响应对象
     */
    private FileUploadResponse convertToResponse(FileUpload fileUpload) {
        User user = userMapper.selectById(fileUpload.getUploadUserId().intValue());
        String username = user != null ? user.getUsername() : "未知用户";
        
        return buildFileUploadResponse(fileUpload, username);
    }
    
    /**
     * 生成文件访问URL
     */
    private String generateFileUrl(String storedFileName) {
        return "http://localhost:" + serverPort + "/uploads/" + storedFileName;
    }
}